//
//  ITScanViewController.m
//  InduceTool
//
//  Created by 魏延龙 on 2020/9/24.
//  Copyright © 2020 魏延龙. All rights reserved.
//

#import "ITScanViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <Masonry/Masonry.h>
#import <JKCategories/JKCategories.h>
@interface ITScanViewController ()<AVCaptureMetadataOutputObjectsDelegate, AVCaptureVideoDataOutputSampleBufferDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate>

@property (strong, nonatomic) UIView *fakeNavView;
@property (strong, nonatomic) UILabel *faketitle;
@property (strong, nonatomic) UIButton *navBackBtn;

@property (strong, nonatomic) UIImageView *overView;
@property (strong, nonatomic) UIImageView *overLineView;
@property (strong, nonatomic) UILabel *tintLbl;
@property (strong, nonatomic) UIButton *bottomBtn;

@property (assign, nonatomic) BOOL isStop;

@property (nonatomic, strong) AVCaptureDevice *device;
@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureVideoDataOutput *videoDataOutput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;

@property (assign, nonatomic) BOOL isBottom;

@property (assign, nonatomic) BOOL needStopScan;

@property (assign, nonatomic) BOOL torchOn;

@end

@implementation ITScanViewController

-(void)dealloc {
    NSLog(@"ITScanViewController release");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor blackColor];
    
    [self createOverView];
    [self createFakeNav];
    
    [self checkCaptureAuth];
   
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    [self.navigationController setNavigationBarHidden:YES];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    self.needStopScan = NO;
    [self startScan];
}

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self stopScan];
}

- (void)checkCaptureAuth {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (status == AVAuthorizationStatusRestricted || status == AVAuthorizationStatusDenied) {
        
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"无相机权限" message:@"扫码登录需要开启相机权限" preferredStyle:UIAlertControllerStyleAlert];
        
        [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            [self.navigationController popViewControllerAnimated:YES];
        }]];
        
        [alertController addAction:[UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }]];
        
        [self presentViewController:alertController animated:YES completion:nil];
        
    } else {
        [self createCapture];
    }
}

- (void)createFakeNav {
    CGFloat staH = 20;
    // iPhone X 顶部多出24距离
//    if (IS_PhoneXAll) {
//        staH += 24;
//    }
    CGFloat navH = staH + 44;
    
    self.fakeNavView = [[UIView alloc] initWithFrame:CGRectZero];
    self.fakeNavView.backgroundColor = [UIColor clearColor];
    [self.view addSubview:self.fakeNavView];
    [self.fakeNavView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.equalTo(self.view);
        make.height.equalTo(@(navH));
    }];
    
    self.navBackBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.navBackBtn.imageView setTintColor:[UIColor whiteColor]];
    [self.navBackBtn setImage:[UIImage imageNamed:@"zscan_back"] forState:UIControlStateNormal];
    [self.navBackBtn addTarget:self action:@selector(navBackBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.fakeNavView addSubview:self.navBackBtn];
    
    self.faketitle = [[UILabel alloc] initWithFrame:CGRectZero];
    self.faketitle.text = @"扫一扫";
    [self.faketitle setTextColor:[UIColor whiteColor]];
    self.faketitle.font = [UIFont systemFontOfSize:18];
    self.faketitle.textAlignment = NSTextAlignmentCenter;
    [self.fakeNavView addSubview:self.faketitle];
    
    UIButton *photoBtn = [UIButton buttonWithType:UIButtonTypeSystem];
    [photoBtn setTitle:@"相册" forState:UIControlStateNormal];
    [self.fakeNavView addSubview:photoBtn];
    [photoBtn addTarget:self action:@selector(photoAction:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.faketitle mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.navBackBtn);
        make.centerX.equalTo(self.fakeNavView);
        make.height.equalTo(@25);
    }];
    
    [self.navBackBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.and.height.equalTo(@28);
        make.left.equalTo(self.fakeNavView).offset(16);
        make.bottom.equalTo(self.fakeNavView.mas_bottom);
    }];
    
    [photoBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.and.height.equalTo(@44);
        make.right.equalTo(self.fakeNavView).offset(-16);
        make.bottom.equalTo(self.fakeNavView.mas_bottom);
    }];
}

- (void)createOverView {
    
    self.overView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"zscan_overview"]];
    [self.view addSubview:_overView];
    [_overView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view).offset(60);
        make.right.equalTo(self.view).offset(-60);
        make.centerY.equalTo(self.view);
        make.height.equalTo(self.overView.mas_width);
    }];
    
    self.overLineView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"zscan_scanline"]];
    [self.view addSubview:_overLineView];
    [_overLineView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.overView);
        make.left.right.equalTo(self.overView);
    }];
    
    UIView *topView = [UIView new];
    topView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    [self.view addSubview:topView];
    [topView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.right.equalTo(self.view);
        make.bottom.equalTo(self.overView.mas_top);
       
    }];
    
    UIView *bottomView = [UIView new];
    bottomView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    [self.view addSubview:bottomView];
    [bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.bottom.right.equalTo(self.view);
        make.top.equalTo(self.overView.mas_bottom);
        
    }];
    
    UIView *leftView = [UIView new];
    leftView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    [self.view addSubview:leftView];
    [leftView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(topView.mas_bottom);
        make.bottom.equalTo(bottomView.mas_top);
        make.left.equalTo(self.view);
        make.right.equalTo(self.overView.mas_left);
    }];
    
    UIView *rightView = [UIView new];
    rightView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    [self.view addSubview:rightView];
    [rightView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(topView.mas_bottom);
        make.bottom.equalTo(bottomView.mas_top);
        make.right.equalTo(self.view);
        make.left.equalTo(self.overView.mas_right);
    }];
    
    self.tintLbl = [UILabel new];
    self.tintLbl.numberOfLines = 2;
    self.tintLbl.textAlignment = NSTextAlignmentCenter;
    self.tintLbl.textColor = [UIColor whiteColor];
    self.tintLbl.text = @"扫描结果";
    self.tintLbl.font = [UIFont systemFontOfSize:16];
    [self.view addSubview:self.tintLbl];
    [self.tintLbl mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.overView.mas_bottom).offset(28);
        make.centerX.equalTo(self.overView);
    }];
    
    self.bottomBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    self.bottomBtn.userInteractionEnabled = YES;
    [self.bottomBtn setTitle:@"闪关灯" forState:UIControlStateNormal];
    [self.bottomBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    self.bottomBtn.titleLabel.font = [UIFont systemFontOfSize:16];
    [self.bottomBtn addTarget:self action:@selector(knowKtbAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.bottomBtn];
    [self.bottomBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.view).offset(-48);
        make.centerX.equalTo(self.overView);
    }];
}

- (void)createCapture {
    // 1、获取摄像设备
    self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    // 2、创建摄像设备输入流
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
    
    // 3、创建元数据输出流
    AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
    [metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    // 设置扫描范围（每一个取值0～1，以屏幕右上角为坐标原点）
    // 注：微信二维码的扫描范围是整个屏幕，这里并没有做处理（可不用设置）;
    // 如需限制扫描框范围，打开下一句注释代码并进行相应调整
    //    metadataOutput.rectOfInterest = CGRectMake(0.05, 0.2, 0.7, 0.6);
    
    // 4、创建会话对象
    _session = [[AVCaptureSession alloc] init];
    // 并设置会话采集率
    _session.sessionPreset = AVCaptureSessionPreset1920x1080;
    
    // 5、添加元数据输出流到会话对象
    [_session addOutput:metadataOutput];
    
    // 创建摄像数据输出流并将其添加到会话对象上,  --> 用于识别光线强弱
    self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
    [_videoDataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
    [_session addOutput:_videoDataOutput];
    
    // 6、添加摄像设备输入流到会话对象
    [_session addInput:deviceInput];
    
    // 7、设置数据输出类型(如下设置为条形码和二维码兼容)，需要将数据输出添加到会话后，才能指定元数据类型，否则会报错
    metadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code,  AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
    
    // 8、实例化预览图层, 用于显示会话对象
    _videoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
    // 保持纵横比；填充层边界
    _videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    CGFloat x = 0;
    CGFloat y = 0;
    CGFloat w = [UIScreen mainScreen].bounds.size.width;
    CGFloat h = [UIScreen mainScreen].bounds.size.height;
    _videoPreviewLayer.frame = CGRectMake(x, y, w, h);
    [self.view.layer insertSublayer:_videoPreviewLayer atIndex:0];
}

#pragma mark - Action

- (void)knowKtbAction:(UIButton *)sender {
    [self turnTorchOn:!self.torchOn];
}

- (void)navBackBtnClicked:(UIButton *)sender {
    [self stopScan];
    [self.navigationController popToRootViewControllerAnimated:YES];
}

-(void)photoAction:(UIButton *)sender {
    [self openPhotoLibrary];
}

- (void)startScan {
    [_session startRunning];
    [self startAnimate];
    self.isStop = NO;
}

- (void)stopScan {
    [_session stopRunning];
    [self stopAnimate];
}

- (void)startAnimate {
   
    float y = 0;
    if (self.isBottom) {
        y = self.overView.jk_top;
        self.isBottom = NO;
    } else {
        y = self.overView.jk_bottom - self.overLineView.jk_height;
        self.isBottom = YES;
    }
    [UIView animateWithDuration:1.5 animations:^{
        self.overLineView.frame = CGRectMake(self.overLineView.jk_left, y, self.overLineView.jk_width, self.overLineView.jk_height);
    } completion:^(BOOL finished) {
        if (!self.isStop) {
            [self startAnimate];
        }
    }];
}

- (void)stopAnimate {
    self.isStop = YES;
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    
    if (self.needStopScan) {
        return;
    }
    
    if (metadataObjects != nil && metadataObjects.count > 0) {
        AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
        NSString *content = obj.stringValue;
        
        // 扫码标记 可以在网络请求失败的时候重新赋值NO，继续扫描
        // self.needStopScan = YES;
        self.tintLbl.text = [NSString stringWithFormat:@"扫描结果: %@", content];
            
    }
}

#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
    NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
    CFRelease(metadataDict);
    NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
    float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
    // brightnessValue 值代表光线强度，值越小代表光线越暗 可以自动打开闪光灯
    if (brightnessValue <= -2 && !self.torchOn) {
        [self turnTorchOn:YES];
    }
}

#pragma mark - UIImagePickerControllerDelegate
// 拍照完成回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey, id> *)info{
    UIImage *image = info[@"UIImagePickerControllerOriginalImage"];
    NSLog(@"finish..");
    if(picker.sourceType == UIImagePickerControllerSourceTypeCamera){
        //图片存入相册
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
    }
    if(picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary){
        [self detectorImage:image];
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}
//进入拍摄页面点击取消按钮
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - 闪光灯
// 打开/关闭手电筒
- (void)turnTorchOn:(BOOL)on{
    if ([self.device hasTorch] && [self.device hasFlash]){

        [self.device lockForConfiguration:nil];
        if (on) {
            [self.device setTorchMode:AVCaptureTorchModeOn];
            [self.device setFlashMode:AVCaptureFlashModeOn];
        } else {
            [self.device setTorchMode:AVCaptureTorchModeOff];
            [self.device setFlashMode:AVCaptureFlashModeOff];
        }
        [self.device unlockForConfiguration];
        self.torchOn = on;
    } else {
        [self.view jk_makeToast:@"当前设备没有闪光灯，不能提供手电筒功能"];
    }
}
#pragma mark - 相册识别
/*** 打开相册  */
-(void)openPhotoLibrary{
    // 进入相册
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
        imagePicker.allowsEditing = YES;
        imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        imagePicker.delegate = self;
        [self presentViewController:imagePicker animated:YES completion:^{
            NSLog(@"打开相册");
        }];
    }else{
        NSLog(@"不能打开相册");
    }
}

// 识别图片二维码
- (void)detectorImage:(UIImage *)image{
    // CIDetector(CIDetector可用于人脸识别)进行图片解析，从而使我们可以便捷的从相册中获取到二维码
    // 声明一个 CIDetector，并设定识别类型 CIDetectorTypeText
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    // 取得识别结果
    NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
    if (features.count == 0) {
        NSLog(@"暂未识别 - - %@", features);
        return;
    } else {
        for (int index = 0; index < [features count]; index ++) {
            CIQRCodeFeature *feature = [features objectAtIndex:index];
            NSLog(@"读取二维码数据信息 - - %@",            @(feature.bounds));
            NSLog(@"读取二维码数据信息2 - - %@",            feature.messageString);
            self.tintLbl.text = [NSString stringWithFormat:@"扫码结果： %@",feature.messageString];
        }
    }
}
@end
